﻿using Modules.System;
using Modules.System.Menu;
using Modules.System.Role;
using PmSoft;
using System.ComponentModel;
using System.Drawing;
using System.Xml.Linq;

namespace ManagementApi.Models.System.Menu
{
    public class RouteDto
    {
        /// <summary>
        /// 路由路径
        /// </summary>
        public string Path { get; set; }

        /// <summary>
        /// 组件路径
        /// </summary>
        public string Component { get; set; }

        /// <summary>
        /// 跳转链接
        /// </summary>
        public string Redirect { get; set; }

        /// <summary>
        /// 路由名称
        /// </summary>
        public string Name { get; set; }

        /// <summary>
        /// 路由属性
        /// </summary>
        public RouteMeta Meta { get; set; }

        /// <summary>
        /// 子路由列表
        /// </summary>
        public IEnumerable<RouteDto> Children { get; set; }

        public class RouteMeta
        {
            /// <summary>
            /// 路由title
            /// </summary>
            public string Title { get; set; }

            /// <summary>
            /// ICON
            /// </summary>
            public string Icon { get; set; }

            /// <summary>
            /// 是否隐藏
            /// </summary>
            public bool Hidden { get; set; }

            /// <summary>
            /// 拥有路由权限的角色编码
            /// </summary>
            public List<string> Roles { get; set; }

            /// <summary>
            /// 是否开启缓存
            /// </summary>
            public bool KeepAlive { get; set; }
        }
    }

    /// <summary>
    /// 系统菜单局部扩展类
    /// </summary>
    public static partial class SysMenuExceptions
    {
        /// <summary>
        /// 转换为VUE路由模型
        /// </summary>
        /// <param name="menus"></param>
        /// <returns></returns>
        public static IEnumerable<RouteDto> AsRoutes(this IEnumerable<SysMenu> menus)
        {
            var menuService = ServiceAccessor.GetService<MenuService>();
            var roleMenus = menuService.GetAllRoleMenus();
            var result = RecurRoutes(0, roleMenus, menus.Where(m => m.Type != MenuType.BUTTON));
            return result;
        }

        private static IEnumerable<RouteDto> RecurRoutes(int parentId, IEnumerable<SysRoleMenu> roleMenus, IEnumerable<SysMenu> menus)
        {
            var routes = new List<RouteDto>();
            var childrens = menus.Where(m => m.ParentId == parentId);
            foreach (var menu in childrens)
            {
                //Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
                RouteDto dto = new();
                if (menu.Type == MenuType.MENU)
                {
                    dto.Name = menu.Path.Replace("-", "");//// 路由 name 需要驼峰，首字母大写
                }
                dto.Path = menu.Path;
                dto.Redirect = menu.Redirect;
                dto.Component = menu.Component;
                dto.Meta = new();
                dto.Meta.Title = menu.Name;
                dto.Meta.Icon = menu.Icon;
                //dto.Meta.Roles = menu.GetRoleCodes().ToList();
                dto.Meta.Roles = roleMenus.Where(a => a.MenuId == menu.MenuId).Select(a => a.RoleCode).ToList();
                dto.Meta.Hidden = !menu.IsVisible;
                dto.Meta.KeepAlive = true;
                dto.Children = RecurRoutes(menu.MenuId, roleMenus, menus);
                routes.Add(dto);
            }
            return routes;
        }

        /// <summary>
        /// 菜单下拉tree
        /// </summary>
        /// <param name="menus"></param>
        /// <returns></returns>
        public static IEnumerable<VueTree<int>> AsOptions(this IEnumerable<SysMenu> menus)
        {
            return RecurOptions(0, menus);
        }

        private static IEnumerable<VueTree<int>> RecurOptions(int parentId, IEnumerable<SysMenu> menus)
        {
            var retMenus = new List<VueTree<int>>();
            var childrens = menus.Where(m => m.ParentId == parentId);
            foreach (var menu in childrens)
            {
                VueTree<int> dto = new VueTree<int>()
                {
                    Label = menu.Name,
                    Value = menu.MenuId,
                    Children = RecurOptions(menu.MenuId, menus)
                };
                retMenus.Add(dto);
            }
            return retMenus;
        }
    }
}